package com.math_space;

import org.springframework.stereotype.Service;

import java.util.LinkedList;
import java.util.List;

/**
 * 解决点击量的接口
 * 考虑问题
 * 1.完成实现接口   40
 * 2.针对(10000/次点击)并发问题 30
 * 3.多线程安全 15
 * 4.对(365 * 24 * 3600), 栈溢出问题进行考虑 15
 */
interface ICounter {
    //每次调用， 累计加 1
    void hit();

    //得到相关的点击量信息
    GradeData getData();
}
class GradeData{

    //最近10秒的平均点击量
    public int time10second;

    //最近10分钟秒的平均点击量
    public int time10minute;

    //最近60分钟的平均点击量
    public int time60minute;

    //最近60秒的点击量列表
    public List<Integer> time60second;

    public int getTime10second() {
        return time10second;
    }

    public void setTime10second(int time10second) {
        this.time10second = time10second;
    }

    public int getTime10minute() {
        return time10minute;
    }

    public void setTime10minute(int time10minute) {
        this.time10minute = time10minute;
    }

    public int getTime60minute() {
        return time60minute;
    }

    public void setTime60minute(int time60minute) {
        this.time60minute = time60minute;
    }

    public List<Integer> getTime60second() {
        return time60second;
    }

    public void setTime60second(List<Integer> time60second) {
        this.time60second = time60second;
    }

    @Override
    public String toString() {
        return "GradeData{" +
                "time10second=" + time10second +
                ", time10minute=" + time10minute +
                ", time60minute=" + time60minute +
                ", time60second=" + time60second +
                '}';
    }
}

class CounterImpl implements ICounter{

    private static Integer count;

    private static long startTime = System.currentTimeMillis();

    static List<Integer> list;

    static {
        count = 0;
        list = new LinkedList<Integer>();
    }

    @Override
    public void hit() {
        long endTime = System.currentTimeMillis();
        count = count + 1;
        //必须一秒钟执行一次
        if((endTime - startTime) == 1000){
            startTime = endTime;
            list.add(count);
            count = 0;
        }
    }

    @Override
    public GradeData getData() {

        GradeData gradeData = new GradeData();
        List<Integer> last60second = new LinkedList<>();
        if(list.size() > 60){
            for(int i = list.size()-1; i >= 0; i--){
                if(i >= (list.size() - 61)){
                    last60second.add(list.get(i));
                }
            }
        }else{
            last60second.addAll(list);
        }
        gradeData.setTime60second(last60second);

        //计算10s平均数
        gradeData.setTime10second(getLastNumAvage(10));

        //计算10分钟平均数
        gradeData.setTime10minute(getLastNumAvage(10 * 60));

        //计算60分钟平均数
        gradeData.setTime60minute(getLastNumAvage(60 * 60));
        return gradeData;
    }

    private synchronized int getLastNumAvage(int second){
        int lastSecond = 0;
        if(list.size() >= second){
            for(int i = list.size()-1; i >= 0; i--){
                if(i >= (list.size() - (second+1))){
                    lastSecond += list.get(i);
                }
            }
            //计算平均数
            lastSecond = lastSecond/second;
        }else{
            for(int num : list){
                lastSecond += num;
            }
            //计算平均数
            lastSecond = lastSecond/list.size();
        }

        return lastSecond;
    }
}
